package Log

import (
	"context"
	"go.mongodb.org/mongo-driver/mongo"
	"go.mongodb.org/mongo-driver/mongo/options"
	"go.uber.org/zap"
	"go.uber.org/zap/zapcore"
	"log"
	"sync"
)

type asyncMongoWriter struct {
	client     *mongo.Client
	collection *mongo.Collection
	logCh      chan []byte
	wg         sync.WaitGroup
}

func newAsyncMongoWriter() *asyncMongoWriter {
	clientOptions := options.Client().ApplyURI("mongodb://192.168.3.242:27017")
	client, err := mongo.Connect(context.Background(), clientOptions)
	if err != nil {
		log.Fatal(err)
	}

	collection := client.Database("AdminLog").Collection("AdminLog")

	return &asyncMongoWriter{
		client:     client,
		collection: collection,
		logCh:      make(chan []byte, 1000), // 可以调整缓冲区大小
		wg:         sync.WaitGroup{},
	}
}

func (w *asyncMongoWriter) startWriter() {
	w.wg.Add(1)
	go func() {
		defer w.wg.Done()
		for logData := range w.logCh {
			_, err := w.collection.InsertOne(context.Background(), map[string]interface{}{"log": string(logData)})
			if err != nil {
				// 可以选择处理错误，例如记录错误日志
				log.Println("Error inserting log into MongoDB:", err)
			}
		}
	}()
}

func (w *asyncMongoWriter) Write(p []byte) (n int, err error) {
	w.logCh <- p
	return len(p), nil
}

func (w *asyncMongoWriter) Sync() error {
	close(w.logCh)
	w.wg.Wait()
	return nil
}

func (w *asyncMongoWriter) Close() error {
	err := w.client.Disconnect(context.Background())
	if err != nil {
		return err
	}
	return nil
}

func InitLoggerWithMongo() *zap.Logger {
	logger, err := zap.NewProduction()
	if err != nil {
		log.Fatal(err)
	}

	asyncWriter := newAsyncMongoWriter()
	asyncWriter.startWriter()

	logger = logger.WithOptions(zap.WrapCore(func(core zapcore.Core) zapcore.Core {
		return zapcore.NewCore(zapcore.NewJSONEncoder(zap.NewProductionEncoderConfig()), asyncWriter, zap.InfoLevel)
	}))

	return logger
}
